/*
 * Copyright (c) 2015 elion All Rights Reserved.
 */
package com.guoyu.project.common.velocity;

import java.io.IOException;
import java.io.Writer;

import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.Node;

/**
 * 定义块，可以被子模板用#override指令覆盖显示
 * 
 * @author: xblibo Date: 2015/5/18 Time: 13:46
 */
public class BlockDirective extends Directive {

    /**
     * 定义块，标签名称
     */
    private final static String BLOCK_TAG = "block";

    /**
     * 定义块，标签名称
     * 
     * @return
     */
    @Override
    public String getName() {
        return BLOCK_TAG;
    }

    @Override
    public int getType() {
        return BLOCK;
    }

    /**
     * 渲染block块
     * 
     * @param context
     * @param writer
     * @param node
     * @return
     * @throws IOException
     * @throws ResourceNotFoundException
     * @throws ParseErrorException
     * @throws MethodInvocationException
     */
    @Override
    public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException,
            ResourceNotFoundException, ParseErrorException, MethodInvocationException {
        String name = VelocitySupports.getRequiredArgument(context, node, 0, getName());

        OverrideNodeWrapper overrideNode = getOverrideNode(context, name);
        Node topNode = node.jjtGetChild(1);
        if (overrideNode == null) {
            return topNode.render(context, writer);
        } else {
            VelocitySupports.setParentForTop(new OverrideNodeWrapper(topNode), overrideNode);
            return overrideNode.render(context, writer);
        }
    }

    private OverrideNodeWrapper getOverrideNode(InternalContextAdapter context, String name) {
        return (OverrideNodeWrapper) context.get(VelocitySupports.getOverrideVariableName(name));
    }
}
